using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using LiteVectorIndex.Engine;
using System.ComponentModel;

namespace LiteVectorIndex
{
    [Icon("pack://application:,,,/LiteVectorIndex;component/Resources/Icon.png")]
    [Category("嵌入式向量库")]
    [OrderWeight(1)]
    public class Cluster_Search : Command, ICommandExecutableInServerSideAsync, IServerCommandParamGenerator
    {
        [FormulaProperty]
        [DisplayName("集合名")]
        public object KBName { get; set; }

        [FormulaProperty]
        [DisplayName("向量（queryEmbedding）")]
        [Description("由浮点数组成的数组，可通过AI大模型生成，形如[0.112,0.9871,...]")]
        public object EmbeddingFormula { get; set; }

        [FormulaProperty]
        [DisplayName("最大返回数量（TopK）")]
        public object TopKFormula { get; set; }

        [DisplayName("将匹配结果保存到变量")]
        [Description("匹配结果为数组，对象的id属性为向量记录的文本ID，score为查询条件与该记录的相似度，数值越高说明越接近")]
        [ResultToProperty]
        public string ResultInParamater { get; set; } = "MatchedArray";


        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var name = (await dataContext.EvaluateFormulaAsync(KBName))?.ToString() ?? "";

            var embedding = await dataContext.EvaluateFormulaAsync(EmbeddingFormula);

            var topK = (await dataContext.EvaluateFormulaAsync(TopKFormula))?.ToString() ?? "3";

            if (string.IsNullOrEmpty(name))
            {
                throw new Exception("集合名不能为空，请检查输入。");
            }

            if (!CollectionManager.Instance.CollectionExists(name))
            {
                throw new Exception("当前向量集合尚未被加载，请先调用【加载向量集合】然后执行本操作。");
            }

            // 获取指定名称的集合  
            var collection = CollectionManager.Instance.GetCollection(name);

            if (collection.Count == 0)
            {
                dataContext.Parameters[ResultInParamater] = Array.Empty<SearchResult>();
                dataContext.Log.AppendLine($"当前向量集合 {name} 为空，无法执行查询，直接返回了空数组。");
            }
            else
            {
                // 执行向量查询
                var result = collection.Search(GeneralConverter.ToVector(embedding), int.Parse(topK));

                dataContext.Log.AppendLine($"在向量集合 {name} 中执行查询，距离计算方法为：{collection.MetricTypeInUse}，同一化：{collection.NormalizeOnAddAndQuery}，返回结果共 {result.Count()} 条结果。");

                // 返回查询结果
                dataContext.Parameters[ResultInParamater] = result;
            }

            return new ExecuteResult();
        }

        public override string ToString()
        {
            return "嵌入式向量库：在向量集合中查询";
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }

        public IEnumerable<GenerateParam> GetGenerateParams()
        {
            yield return new GenerateListParam()
            {
                ParamName = this.ResultInParamater,
                Description = "查询结果",
                ParamScope = CommandScope.All,
                ItemProperties = new List<string>() {
                    "id",
                    "score"
                }
            };
        }
    }
}
